const WebSocket = require('ws');
const WebSocketServer = WebSocket.WebSocketServer;
const wss = new WebSocketServer({ port: 8000 });

// 在线用户映射
let onlineUserMap = new Map();

const WebSocketType = {
    Error: 0, //错误
    GroupChat: 1,
    SingleChat: 2,
    Position: 3, //我的大厅位置
    AllPositions: 4, //所有人大厅位置
}
wss.on('connection', function connection(ws, req) {
    const url = new URL(req.url, `http://${req.headers.host}`);
    const userId = url.searchParams.get('id');

    ws.userId = userId; // 保存 userId 到 ws 对象上
    console.log("userId: " + userId);

    // 先判断在线用户中有没有这个映射 再将用户添加到在线用户映射
    if (!onlineUserMap.has(userId)) {
        onlineUserMap.set(userId, getRandomPosition());
    }
    //遍历打印onlineUserMap
    for (let [key, value] of onlineUserMap) {
        console.log(`用户 ${key} 的位置: ${value.x}, ${value.y}`);
    }
    //给当前用户发送位置信息
    sendToUser(userId, { type: WebSocketType.Position, position: onlineUserMap.get(userId) });
    sendToUser(userId, { type: WebSocketType.AllPositions, positions: getOccupiedPositions() });

    ws.on('message', function message(data) {
        console.log('received: %s', data);

        // 广播消息给其他客户端
        wss.clients.forEach(function each(client) {
            if (client !== ws && client.readyState === WebSocket.OPEN) {
                client.send(data); // data 可以是 JSON 字符串
            }
        });
    });

    ws.on('close', () => {
        console.log(`用户 ${userId} 断开连接`);
    });
});

// 给指定 userId 的客户端发消息
function sendToUser(userId, message) {
    wss.clients.forEach(client => {
        if (client.readyState === WebSocket.OPEN && client.userId === userId) {
            client.send(JSON.stringify(message));
        }
    });
}


// 获取所有已占用的位置
function getOccupiedPositions() {
    return Array.from(onlineUserMap.values()).map(pos => `${pos.x},${pos.y}`);
}

/**
 * 生成随机坐标函数
 * @returns {Object} 随机坐标对象 { x, y }
 */
function getRandomPosition() {
    const min = 25;
    const max = 375;
    const step = 25;
    const steps = (max - min) / step + 1; // 15
    const occupied = new Set(getOccupiedPositions());

    if (occupied.size >= steps * steps) {
        throw new Error("没有空余位置了");
    }

    let x, y;
    do {
        x = min + Math.floor(Math.random() * steps) * step;
        y = min + Math.floor(Math.random() * steps) * step;
    } while (occupied.has(`${x},${y}`));

    return { x, y };
}



module.exports = { wss, sendToUser };


